package com.snack.shop.controller;

import cn.dev33.satoken.stp.StpUtil;
import com.snack.shop.common.BusinessException;
import com.snack.shop.common.Result;
import com.snack.shop.dto.WxPayNotifyResult;
import com.snack.shop.dto.WxPayRequestDTO;
import com.snack.shop.dto.WxPayResponseDTO;
import com.snack.shop.entity.Order;
import com.snack.shop.service.OrderService;
import com.snack.shop.service.WxPayService;
import com.snack.shop.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 支付控制器
 */
@Slf4j
@Tag(name = "支付管理")
@RestController
@RequestMapping("/payment")
@RequiredArgsConstructor
public class PaymentController {

    private final WxPayService wxPayService;
    private final OrderService orderService;
    private final UserService userService;

    @Operation(summary = "创建微信支付订单")
    @PostMapping("/wxpay/create")
    public Result<WxPayResponseDTO> createWxPayOrder(@Validated @RequestBody WxPayRequestDTO param) {
        Long userId = StpUtil.getLoginIdAsLong();
        
        // 获取订单信息
        Order order = orderService.getDetail(param.getOrderId());
        
        // 验证订单归属
        if (!order.getUserId().equals(userId)) {
            throw new BusinessException("无权操作该订单");
        }
        
        // 验证订单状态
        if (order.getStatus() != 0) {
            throw new BusinessException("订单状态不正确，当前状态：" + order.getStatus());
        }
        
        // 验证/兜底 openid
        String openid = param.getOpenid();
        if (openid == null || openid.isEmpty()) {
            // 从数据库中兜底读取
            openid = userService.getUserById(userId).getOpenid();
            if (openid == null || openid.isEmpty()) {
                throw new BusinessException("用户openid不能为空，请先通过微信授权获取openid");
            }
        }
        
        log.info("创建支付订单：userId={}, orderId={}, orderNo={}, amount={}", 
                userId, order.getId(), order.getOrderNo(), order.getActualAmount());
        
        // 创建预支付订单
        WxPayResponseDTO response = wxPayService.createPrepayOrder(order, openid);
        
        // 更新订单的prepay_id和pay_type
        order.setPrepayId(response.getPackageValue().replace("prepay_id=", ""));
        order.setPayType(1); // 1-微信支付
        orderService.updateById(order);
        
        return Result.success(response);
    }

    @Operation(summary = "查询订单支付状态")
    @GetMapping("/wxpay/query/{orderId}")
    public Result<Map<String, Object>> queryPayStatus(@PathVariable Long orderId) {
        Long userId = StpUtil.getLoginIdAsLong();
        
        // 获取订单信息
        Order order = orderService.getDetail(orderId);
        
        // 验证订单归属
        if (!order.getUserId().equals(userId)) {
            throw new BusinessException("无权操作该订单");
        }
        
        // 如果订单已支付，直接返回
        if (order.getStatus() > 0) {
            Map<String, Object> result = new HashMap<>();
            result.put("paid", true);
            result.put("status", order.getStatus());
            result.put("transactionId", order.getTransactionId());
            return Result.success(result);
        }
        
        // 查询微信支付状态
        try {
            WxPayNotifyResult payResult = wxPayService.queryOrderStatus(order.getOrderNo());
            
            // 判断支付状态
            boolean paid = "SUCCESS".equals(payResult.getTradeState());
            
            // 如果支付成功，更新订单状态
            if (paid) {
                orderService.handlePaySuccess(order.getOrderNo(), payResult.getTransactionId());
            }
            
            Map<String, Object> result = new HashMap<>();
            result.put("paid", paid);
            result.put("tradeState", payResult.getTradeState());
            result.put("tradeStateDesc", payResult.getTradeStateDesc());
            result.put("transactionId", payResult.getTransactionId());
            
            return Result.success(result);
            
        } catch (Exception e) {
            log.error("查询支付状态失败：orderId={}", orderId, e);
            
            // 查询失败时返回订单当前状态
            Map<String, Object> result = new HashMap<>();
            result.put("paid", false);
            result.put("status", order.getStatus());
            result.put("error", e.getMessage());
            
            return Result.success(result);
        }
    }

    @Operation(summary = "微信支付回调通知")
    @PostMapping("/wxpay/notify")
    public Map<String, String> wxPayNotify(HttpServletRequest request) {
        try {
            // 读取请求体
            String requestBody = readRequestBody(request);
            
            // 获取请求头
            String signature = request.getHeader("Wechatpay-Signature");
            String serial = request.getHeader("Wechatpay-Serial");
            String timestamp = request.getHeader("Wechatpay-Timestamp");
            String nonce = request.getHeader("Wechatpay-Nonce");
            
            log.info("收到微信支付回调通知：timestamp={}, nonce={}, serial={}", timestamp, nonce, serial);
            
            // 处理回调通知
            WxPayNotifyResult payResult = wxPayService.handlePayNotify(
                    requestBody, signature, serial, timestamp, nonce);
            
            // 判断支付状态
            if ("SUCCESS".equals(payResult.getTradeState())) {
                // 更新订单状态
                orderService.handlePaySuccess(payResult.getOutTradeNo(), payResult.getTransactionId());
                
                log.info("支付成功，订单已更新：orderNo={}, transactionId={}", 
                        payResult.getOutTradeNo(), payResult.getTransactionId());
            }
            
            // 返回成功响应
            Map<String, String> response = new HashMap<>();
            response.put("code", "SUCCESS");
            response.put("message", "成功");
            return response;
            
        } catch (Exception e) {
            log.error("处理微信支付回调失败", e);
            
            // 返回失败响应
            Map<String, String> response = new HashMap<>();
            response.put("code", "FAIL");
            response.put("message", e.getMessage());
            return response;
        }
    }

    @Operation(summary = "申请退款")
    @PostMapping("/wxpay/refund/{orderId}")
    public Result<String> refund(
            @PathVariable Long orderId,
            @Parameter(description = "退款原因") @RequestParam(required = false) String reason) {
        Long userId = StpUtil.getLoginIdAsLong();
        
        // 获取订单信息
        Order order = orderService.getDetail(orderId);
        
        // 验证订单归属
        if (!order.getUserId().equals(userId)) {
            throw new BusinessException("无权操作该订单");
        }
        
        // 验证订单状态（只有已支付的订单才能退款）
        if (order.getStatus() == 0) {
            throw new BusinessException("订单未支付，无法退款");
        }
        
        if (order.getStatus() >= 7) {
            throw new BusinessException("订单已取消或已退款");
        }
        
        // 申请退款
        String refundNo = wxPayService.refund(order, reason);
        
        // 更新订单状态为已退款
        orderService.handleRefund(orderId);
        
        log.info("退款申请成功：orderId={}, refundNo={}, reason={}", orderId, refundNo, reason);
        
        return Result.success(refundNo);
    }

    /**
     * 读取请求体
     */
    private String readRequestBody(HttpServletRequest request) throws IOException {
        BufferedReader reader = request.getReader();
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
        return sb.toString();
    }
}

